class Animal {
    public String name;
    public int age;
    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void eat() {
        System.out.println(this.name + "正在吃....");
    }
}
class Dog extends Animal {
    public String color;
    public Dog(String name,int age,String color) {
        super(name,age);
        this.color = color;
    }
    public void barks() {
        System.out.println(this.name + "正在汪汪叫...");
    }
    public void eat() {
        System.out.println(this.name + "正在吃狗粮....");

    }
}
class Bird extends Animal {
    public Bird(String name,int age) {
        super(name,age);
    }
    public void eat() {
        System.out.println(this.name + "吃虫子...");
    }
    public void fly() {
        System.out.println(this.name + "正在飞....");
    }
}
public class Test {
    public static void main(String[] args) {
        //向上转型： 父接收子
        Bird bird = new Bird("布谷",1);
        Animal animal1 = bird;
        animal1.eat();
        Dog dog = new Dog("小黑",2,"黑色");
        Animal animal2 = dog;
        animal2.eat();
        //向下转型： 父强转为子，不安全使用功能 instanceof
        if(animal1 instanceof Bird) {
            bird = (Bird)animal1;
            bird.fly();
        }else {
            System.out.println("不属于鸟类");
        }
      if(animal2 instanceof Dog) {
          dog = (Dog)animal2;
          dog.barks();
      }else {
          System.out.println("不属于犬类");
      }

    }
    public static void main4(String[] args) {
        //重写:外壳不变，核心重写
        //4 重写规则：
        //4.1 重写不能改变方法名，返回值，参数，如果返回值构成继承关系则可以进行修改（协变类型）
        //4.2 不能修改 static private final 类型
        //4.3 子类访问限定修饰符必须 >= 父类方法限定修饰符
        //4.4 重写方法可以使用@Override进行注解，可以进行合法性校验
        //重写设计规则：向上兼容老版本功能，原有基础上添加新的功能
        //静态绑定（早绑定）：编译时通过传参类型已经确定了调用那个方法 例：函数重载
        //动态绑定（晚绑定）：编译时不确定调用那个方法，只有运行时才确定调用那个类方法
    }
    public static void func(Animal animal) {
        animal.eat();
    }
    public static Animal func2() {//2.3
        return new Bird("布谷鸟",1);
    }
    public static void main3(String[] args) {
        //向上转型
        //2.1直接赋值
        //Animal animal1 = new Dog("大黄",1,"黄色");
        //2.2传参
        Dog dog = new Dog("大黄",1,"黄色");
        func(dog);
        Bird bird = new Bird("布谷",1);
        func(bird);
        //2.3通过返回值
        //多态:不同对象完成同一个行为时，返回不同的状态
        //3个条件
        //3.1 必须在继承体系下
        //3.2 子类对父类方法进行重写
        //3.3 父类方法引用调用重写方法
    }
    public static void main2(String[] args) {
        Animal animal = new Dog("小灰",2,"灰色");//向上转型：父类接收子类实例化对象
        animal.eat();//动态绑定
        //animal.barks();//error 父类不能调用子类方法
        //重写
        //1.1 方法名相同
        //1.2 参数相同
        //1.3 返回值相同
        //1.4 重写方法内容
    }
    public static void main1(String[] args) {
        Dog dog = new Dog("小黑",1,"黑色");//实例化对象
        dog.barks();
        dog.eat();
    }
}
